package com.google.code.head2head.dao;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.log4j.Logger;

public abstract class AbstractDao<T> {

	
	private EntityManager entityManager;
	private static final Logger LOG = Logger.getLogger(AbstractDao.class);
	private Class<T> domainClass;
	
	/**
	 * Return the domain class linked to this dao
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	protected Class<T> getDomainClass() {
		if (domainClass == null) {
			ParameterizedType thisType = (ParameterizedType) getClass()
					.getGenericSuperclass();
			domainClass = (Class) thisType.getActualTypeArguments()[0];
		}
		return domainClass;
	}

	
    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this. entityManager = entityManager;
    }
	
	public void save(T object){
		LOG.debug("perisisting "+object);
		entityManager.persist(object);
		LOG.debug("finished perisisting "+object);
	}
	
	@SuppressWarnings("unchecked")
	public List<T> findAll(int first, int last) {
		Query q=entityManager.createQuery("from "+getDomainClass().getCanonicalName());
		q.setFirstResult(first);
		q.setMaxResults(last);
		return q.getResultList();
	}

	@SuppressWarnings("unchecked")
	public List<T> findAll() {
		Query q=entityManager.createQuery("from "+getDomainClass().getCanonicalName()+" as o");
		return q.getResultList();
	}
	
	public void update(T object){
		entityManager.merge(object);
	}
	
	public T getEntity(long id){
		return entityManager.find(getDomainClass(), id);
	}
	


	public EntityManager getEntityManager() {
		return entityManager;
	}
	
}
